<?php


namespace app\common\server;

class MakeZip
{
	public function zip($dir_path, $zipName)
	{
		try {
			$relationArr = [$dir_path => ["originName" => $dir_path, "is_dir" => true, "encode" => "", "children" => []]];
			$this->modifiyFileName($dir_path, $relationArr[$dir_path]["children"]);
			$zip = new \ZipArchive();
			$zip->open($zipName, \ZipArchive::CREATE);
			$this->zipDir(array_keys($relationArr)[0], "", $zip, array_values($relationArr)[0]["children"]);
			$zip->close();
			$this->restoreFileName(array_keys($relationArr)[0], array_values($relationArr)[0]["children"]);
			return true;
		} catch (\Exception $exception) {
			return false;
		}
	}
	private function zipDir($real_path, $zip_path, &$zip, $relationArr)
	{
		$sub_zip_path = empty($zip_path) ? "" : $zip_path . DIRECTORY_SEPARATOR;
		if (is_dir($real_path)) {
			foreach ($relationArr as $k => $v) {
				if ($v["is_dir"]) {
					$zip->addEmptyDir($sub_zip_path . $v["originName"]);
					$this->zipDir($real_path . DIRECTORY_SEPARATOR . $k, $sub_zip_path . $v["originName"], $zip, $v["children"]);
				} else {
					$zip->addFile($real_path . DIRECTORY_SEPARATOR . $k, $sub_zip_path . $k);
					$zip->deleteName($sub_zip_path . $v["originName"]);
					$zip->renameName($sub_zip_path . $k, $sub_zip_path . $v["originName"]);
				}
			}
		}
	}
	private function modifiyFileName($path, &$relationArr)
	{
		if (!is_dir($path) || !is_array($relationArr)) {
			return false;
		}
		if ($dh = opendir($path)) {
			$count = 0;
			while (($file = readdir($dh)) !== false) {
				if (in_array($file, [".", "..", null])) {
				} else {
					$encode = mb_detect_encoding($file, ["ASCII", "UTF-8", "GB2312", "GBK", "BIG5"]);
					if (is_dir($path . DIRECTORY_SEPARATOR . $file)) {
						$newName = md5(rand(0, 99999) . rand(0, 99999) . rand(0, 99999) . microtime() . "dir" . $count);
						$relationArr[$newName] = ["originName" => iconv($encode, "UTF-8", $file), "is_dir" => true, "encode" => $encode, "children" => []];
						rename($path . DIRECTORY_SEPARATOR . $file, $path . DIRECTORY_SEPARATOR . $newName);
						$this->modifiyFileName($path . DIRECTORY_SEPARATOR . $newName, $relationArr[$newName]["children"]);
						$count++;
					} else {
						$extension = strchr($file, ".");
						$newName = md5(rand(0, 99999) . rand(0, 99999) . rand(0, 99999) . microtime() . "file" . $count);
						$relationArr[$newName . $extension] = ["originName" => iconv($encode, "UTF-8", $file), "is_dir" => false, "encode" => $encode, "children" => []];
						rename($path . DIRECTORY_SEPARATOR . $file, $path . DIRECTORY_SEPARATOR . $newName . $extension);
						$count++;
					}
				}
			}
		}
	}
	private function restoreFileName($path, $relationArr)
	{
		foreach ($relationArr as $k => $v) {
			if (!empty($v["children"])) {
				$this->restoreFileName($path . DIRECTORY_SEPARATOR . $k, $v["children"]);
				rename($path . DIRECTORY_SEPARATOR . $k, iconv("UTF-8", $v["encode"], $path . DIRECTORY_SEPARATOR . $v["originName"]));
			} else {
				rename($path . DIRECTORY_SEPARATOR . $k, iconv("UTF-8", $v["encode"], $path . DIRECTORY_SEPARATOR . $v["originName"]));
			}
		}
	}
}